package com.evil.common.activiti.enums;

import com.evil.common.core.enums.RCodeEnum;
import com.evil.common.core.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.Optional;

/**
 * 节点类型
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@AllArgsConstructor
public enum NodeTypeEnum {
    /**
     * 节点类型(0: 开始节点, 1: 结束节点, 2: 网关节点, 3:审批节点, 4:填写节点, 5:抄送节点, )
     */
    START_EVENT(0, false, false, false, "开始节点", "开始节点", null),
    END_EVENT(1, false, false, false, "结束节点", "结束节点", null),
    INCLUSIVE_GATEWAY_NODE(2, false, true, false, "网关节点", "网关节点", null),
    APPROVAL_NODE(3, false, true, true, "审批节点", "未命名节点", HandleTypeEnum.APPROVED),
    FILL_IN_NODE(4, false, true, true, "填写节点", "未命名节点", HandleTypeEnum.SUBMIT),
    CARBON_COPY_NODE(5, false, true, true, "抄送节点", "未命名节点", null),

    // 排他网关（审核拒绝/流程回退）
    EXCLUSIVE_GATEWAY_NODE(6, true, false, false, "排他网关节点", "排他网关节点", null),
    BOUNDARY_EVENT_NODE(7, true, false, false, "边界事件节点", "边界事件节点", null),
    // 排他网关（网关汇集使用）
    BRANCH_INCLUSIVE_GATEWAY_NODE(8, true, false, false, "网关汇集网关节点", "网关汇集网关节点", null),

    ADD_ROBOT_NODE(9, false, true, true, "Robot·自动添加数据", "Robot·自动添加数据", null),
    MODIFY_ROBOT_NODE(10, false, true, true, "Robot·自动更新数据", "Robot·自动更新数据", null),
    ;

    @Getter
    private final int id;
    @Getter
    private final boolean isPrivate;
    @Getter
    private final boolean canAdd;
    /**
     * 是否有处理人
     */
    @Getter
    private final boolean hasHandler;
    @Getter
    private final String name;
    @Getter
    private final String defaultNodeName;
    /**
     * 流程完成操作类型，为空则设为没有完成操作类型
     */
    @Getter
    private final HandleTypeEnum completedHandlerType;

    /**
     * 是否可以回退
     *
     * @return boolean
     */
    public boolean canFallback() {
        return APPROVAL_NODE.getId() == this.getId() || FILL_IN_NODE.getId() == this.getId();
    }

    /**
     * 是否是网关节点
     *
     * @return boolean
     */
    public boolean isGateway() {
        return INCLUSIVE_GATEWAY_NODE.getId() == this.getId()
                || EXCLUSIVE_GATEWAY_NODE.getId() == this.getId()
                || BRANCH_INCLUSIVE_GATEWAY_NODE.getId() == this.getId();
    }

    /**
     * 是否是机器人节点
     *
     * @return boolean
     */
    public boolean isRobot() {
        return ADD_ROBOT_NODE.getId() == this.getId() || MODIFY_ROBOT_NODE.getId() == this.getId();
    }

    /**
     * 是否是用户节点
     *
     * @return boolean
     */
    public boolean isUserTask() {
        return APPROVAL_NODE.getId() == this.getId()
                || FILL_IN_NODE.getId() == this.getId()
                || CARBON_COPY_NODE.getId() == this.getId();
    }

    /**
     * 是否有控件权限
     *
     * @return boolean
     */
    public boolean hasControlPermission() {
        return START_EVENT.getId() == this.getId() || this.isUserTask();
    }

    public static Optional<NodeTypeEnum> findById(Integer id) {
        if (null == id) {
            return Optional.empty();
        }
        return Arrays.stream(values()).filter(e -> e.id == id).findFirst();
    }

    public static NodeTypeEnum isExistById(Integer id) {
        return NodeTypeEnum.findById(id).orElseThrow(NodeTypeEnum::getBusinessException);
    }

    public static BusinessException getBusinessException() {
        return new BusinessException(RCodeEnum.ERROR_PARAMETER, "流程节点类型参数错误");
    }
}
